package cn.csg.ams.collect2.poptopics.service.impl;

import cn.csg.ams.collect2.poptopics.dao.MkMcTermAlarmLogDao;
import cn.csg.ams.collect2.poptopics.entity.LoadData;
import cn.csg.ams.collect2.poptopics.entity.RecordInfo;
import cn.csg.ams.collect2.poptopics.infrastructure.utils.JsonUtil;
import cn.csg.ams.collect2.poptopics.service.MkMcTermAlarmLogService;
import cn.hutool.core.util.StrUtil;
import com.aliyun.datahub.client.model.TupleRecordData;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * @author: zhanggang
 * @ClassName: MkMcTermAlarmLogServiceImpl
 * @date: 2023-11-15 16:31:51
 * @Description: 停复电告警数据消费日志(mk_mc_term_alarm_log)表服务实现类
 */
@Service("mkMcTermAlarmLogService")
public class MkMcTermAlarmLogServiceImpl implements MkMcTermAlarmLogService {

    private static Logger logger = LoggerFactory.getLogger(MkMcTermAlarmLogServiceImpl.class);

    @Autowired
    private MkMcTermAlarmLogDao mkMcTermAlarmLogDao;

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final String RECORD_INFO_KEY = "RECORD_INFO_";

    private static final String NO_RECORD_INFO = "not runMeterId data";

    /**
     * 插入停复电告警日志-清洗前
     *
     * @param data 消费数据
     * @return 影响行数
     */
    @Override
    public void saveMkMcTermAlarmLogPre(TupleRecordData data) {
        CompletableFuture.runAsync(() -> {
            List<Object> fields = new ArrayList<>();
            for (int i = 0; i < data.getRecordSchema().getFields().size(); i++) {
                fields.add(data.getField(i));
            }
            // 数据时间
            Date endTime = new Date();
            fields.add(new SimpleDateFormat("yyyyMMddHHmmss").format(endTime));

            try {
                mkMcTermAlarmLogDao.insertMkMcTermAlarmLogPre(fields);
            } catch (Exception e) {
                logger.error("清洗前告警日志插入失败");
            }
        });
    }


    /**
     * 插入停复电告警日志-清洗后
     *
     * @param data      消费数据
     * @param startTime
     * @return 影响行数
     */
    @Override
    public void saveMkMcTermAlarmLog(TupleRecordData data, long startTime, long systemTime) {
        CompletableFuture.runAsync(() -> {
            List<Object> fields = new ArrayList<>();
            for (int i = 0; i < data.getRecordSchema().getFields().size(); i++) {
                fields.add(data.getField(i));
            }
            // 数据时间
            Date endTime = new Date();
            fields.add(new SimpleDateFormat("yyyyMMddHHmmss").format(endTime));
            // 开始时间
            fields.add(startTime);
            // 结束时间
            fields.add(endTime.getTime());
            // s数据进入datahub的时间
            fields.add(systemTime);

            try {
                mkMcTermAlarmLogDao.insertMkMcTermAlarmLog(fields);
            } catch (Exception e) {
                logger.error("数据重复消费", e);
            }
        });
    }


    /**
     * 根据运行电能表标识查询档案信息
     *
     * @param runMeterId 运行电能表标识
     * @return RecordInfo
     */
    @Override
    public RecordInfo getRecordInfo(String runMeterId, String areaCode) {
        // 查询redis
        String key = getKey(runMeterId, areaCode);
        String value = redisTemplate.opsForValue().get(key);
        if (NO_RECORD_INFO.equals(value)) {
            return null;
        }

        if (StrUtil.isNotBlank(value) && value.startsWith("{")) {
            return JsonUtil.toObject(value, RecordInfo.class);
        }

        // redis中没有，在查询数据库, 同时添加到redis中
        RecordInfo recordInfo = mkMcTermAlarmLogDao.getRecordInfo(runMeterId, areaCode);
        if (recordInfo == null) {
            redisTemplate.opsForValue().set(key, NO_RECORD_INFO, 12, TimeUnit.HOURS);
            return null;
        }
        redisTemplate.opsForValue().set(key, JsonUtil.toJson(recordInfo), 7, TimeUnit.DAYS);
        return recordInfo;
    }


    @Override
    public RecordInfo getRecordInfoByTerm(String runTermId, String areaCode) {
        // 查询redis
        String key = getKey(runTermId, areaCode);
        String value = redisTemplate.opsForValue().get(key);
        if (StrUtil.isNotBlank(value) && value.startsWith("{")) {
            return JsonUtil.toObject(value, RecordInfo.class);
        }

        // redis中没有，在查询数据库, 同时添加到redis中
        RecordInfo recordInfo = mkMcTermAlarmLogDao.getRecordInfoByTerm(runTermId, areaCode);
        redisTemplate.opsForValue().set(key, JsonUtil.toJson(recordInfo), 7, TimeUnit.DAYS);
        return recordInfo;
    }

    private String getKey(String runMeterId, String areaCode) {
        return RECORD_INFO_KEY + areaCode + "_" + runMeterId;
    }


    /**
     * 召测
     *
     * @param runMeterId 运行电能表标识
     */
    @Override
    public LoadData getLoadDataByRunMeterId(String runMeterId) {
        LoadData loadData = new LoadData();
        loadData.setRunMeterId(runMeterId);
        loadData.setCurrA(new BigDecimal(66));
        loadData.setCurrB(new BigDecimal(66));
        loadData.setCurrC(new BigDecimal(66));
        loadData.setVoltA(new BigDecimal(66));
        loadData.setVoltB(new BigDecimal(66));
        loadData.setVoltC(new BigDecimal(66));
        return loadData;
    }


    /**
     * 查询公变台区下的配置终端标识与电表标识
     *
     * @param taNo 台区编号
     * @return Map<String, String>
     */
    @Override
    public Map<String, String> getPbTermAndMeterByTaNo(String taNo, String taType) {
        return mkMcTermAlarmLogDao.getPbTermAndMeterByTaNo(taNo, taType);
    }
}
